package com.pt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pt.common.constant.UserConstant;
import com.pt.common.enums.UserClass;
import com.pt.common.enums.UserStatus;
import com.pt.dto.request.LoginRequest;
import com.pt.dto.request.RegisterRequest;
import com.pt.dto.request.UpdateProfileRequest;
import com.pt.dto.request.ChangePasswordRequest;
import com.pt.dto.request.UserSettingsRequest;
import com.pt.dto.response.AuthResponse;
import com.pt.dto.response.UserStatsResponse;
import com.pt.dto.response.UserProfileResponse;
import com.pt.dto.response.UserSettingsResponse;
import com.pt.entity.Invitation;
import com.pt.entity.Peer;
import com.pt.entity.Torrent;
import com.pt.entity.User;
import com.pt.entity.UserBonusLog;
import com.pt.entity.UserDailyDownload;
import com.pt.mapper.InvitationMapper;
import com.pt.mapper.PeerMapper;
import com.pt.mapper.UserBonusLogMapper;
import com.pt.mapper.UserMapper;
import com.pt.mapper.UserDailyDownloadMapper;
import com.pt.security.JwtTokenProvider;
import com.pt.security.UserPrincipal;
import com.pt.service.InvitationService;
import com.pt.service.TorrentService;
import com.pt.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserDailyDownloadMapper userDailyDownloadMapper;

    private final JwtTokenProvider tokenProvider;
    private final PasswordEncoder passwordEncoder;
    private final InvitationMapper invitationMapper;
    private final UserBonusLogMapper userBonusLogMapper;
    private final PeerMapper peerMapper;
    private final TorrentService torrentService;
    private final UserDetailsService userDetailsService;
    
    private final AuthenticationManager authenticationManager;
    
    // 用于控制同时下载限制的缓存
    private final Map<Long, Integer> activeDownloadsCache = new ConcurrentHashMap<>();
    // 用于控制每日下载限制的缓存
    private final Map<String, Integer> dailyDownloadsCache = new ConcurrentHashMap<>();
    private final Map<String, Long> dailyDownloadsExpireTime = new ConcurrentHashMap<>();

    @Autowired
    public UserServiceImpl(
            JwtTokenProvider tokenProvider,
            PasswordEncoder passwordEncoder,
            InvitationMapper invitationMapper,
            UserBonusLogMapper userBonusLogMapper,
            PeerMapper peerMapper,
            @Lazy TorrentService torrentService,
            UserDetailsService userDetailsService,
            @Lazy AuthenticationManager authenticationManager) {
        this.tokenProvider = tokenProvider;
        this.passwordEncoder = passwordEncoder;
        this.invitationMapper = invitationMapper;
        this.userBonusLogMapper = userBonusLogMapper;
        this.peerMapper = peerMapper;
        this.torrentService = torrentService;
        this.userDetailsService = userDetailsService;
        this.authenticationManager = authenticationManager;
    }

    @Override
    @Transactional
    public AuthResponse register(RegisterRequest request) {
        // 验证邀请码
        Invitation invitation = invitationMapper.selectOne(
                new LambdaQueryWrapper<Invitation>()
                        .eq(Invitation::getCode, request.getInvitationCode())
                        .eq(Invitation::getStatus, 0)
        );
        
        if (invitation == null) {
            throw new RuntimeException("无效的邀请码");
        }
        
        // 验证用户名是否已存在
        boolean exists = lambdaQuery().eq(User::getUsername, request.getUsername()).exists();
        if (exists) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 验证邮箱是否已存在
        exists = lambdaQuery().eq(User::getEmail, request.getEmail()).exists();
        if (exists) {
            throw new RuntimeException("邮箱已被注册");
        }
        
        // 创建用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setStatus(UserStatus.NORMAL.getCode());
        user.setUserClass(UserClass.NORMAL.getCode());
        user.setUploaded(0L);
        user.setDownloaded(0L);
        user.setBonusPoints(0);
        user.setPasskey(generatePasskey());
        user.setInvitedBy(invitation.getUserId());
        user.setCreatedTime(LocalDateTime.now());
        
        // 设置考核期限（30天）
        user.setAssessmentDeadline(LocalDateTime.now().plusDays(30));
        user.setWarningCount(0);
        
        // 保存用户
        save(user);
        
        // 更新邀请码状态
        invitation.setStatus(1);
        invitation.setUsedBy(user.getId());
        invitation.setUsedTime(LocalDateTime.now());
        invitationMapper.updateById(invitation);
        
        // 通过UserDetailsService加载用户并创建验证凭证
        UserDetails userDetails = userDetailsService.loadUserByUsername(request.getUsername());
        UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        
        // 生成JWT令牌
        String token = tokenProvider.generateToken(authentication);
        
        return new AuthResponse(token, "注册成功");
    }

    @Override
    @Transactional
    public void registerUser(RegisterRequest request) {
        System.out.println("=== 注册用户开始 ===");
        System.out.println("邀请码: " + request.getInvitationCode());
        
        // 验证邀请码
        Invitation invitation = invitationMapper.selectOne(
                new LambdaQueryWrapper<Invitation>()
                        .eq(Invitation::getCode, request.getInvitationCode())
                        .eq(Invitation::getStatus, 0)
        );
        
        System.out.println("数据库查询结果: " + invitation);
        
        if (invitation == null) {
            // 查看数据库中所有的邀请码状态
            List<Invitation> allInvitations = invitationMapper.selectList(null);
            System.out.println("数据库中所有邀请码：");
            for (Invitation inv : allInvitations) {
                System.out.println("Code: " + inv.getCode() + ", Status: " + inv.getStatus());
            }
            throw new RuntimeException("无效的邀请码");
        }
        
        // 验证用户名是否已存在
        boolean exists = lambdaQuery().eq(User::getUsername, request.getUsername()).exists();
        if (exists) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 验证邮箱是否已存在
        exists = lambdaQuery().eq(User::getEmail, request.getEmail()).exists();
        if (exists) {
            throw new RuntimeException("邮箱已被注册");
        }
        
        // 创建用户（状态为待验证）
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setStatus(UserStatus.UNVERIFIED.getCode()); // 设置为待验证状态
        user.setUserClass(UserClass.NORMAL.getCode());
        user.setUploaded(0L);
        user.setDownloaded(0L);
        user.setBonusPoints(0);
        user.setPasskey(generatePasskey());
        user.setInvitedBy(invitation.getUserId());
        user.setCreatedTime(LocalDateTime.now());
        
        // 设置考核期限（30天）
        user.setAssessmentDeadline(LocalDateTime.now().plusDays(30));
        user.setWarningCount(0);
        
        // 保存用户
        save(user);
        
        // 更新邀请码状态
        invitation.setStatus(1);
        invitation.setUsedBy(user.getId());
        invitation.setUsedTime(LocalDateTime.now());
        invitationMapper.updateById(invitation);
    }

    @Override
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication != null && authentication.getPrincipal() instanceof UserPrincipal) {
            UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
            
            // 如果UserPrincipal中有用户名，直接使用
            if (userPrincipal.getUsername() != null) {
                return getUserByUsername(userPrincipal.getUsername());
            }
            
            // 如果没有用户名但有ID，通过ID查询
            if (userPrincipal.getId() != null && userPrincipal.getId() > 0) {
                return getById(userPrincipal.getId());
            }
        }
        
        // 作为后备方案，尝试解析authentication.getName()
        String name = authentication.getName();
        
        // 如果名称是数字，则当作用户ID处理
        try {
            Long userId = Long.parseLong(name);
            return getById(userId);
        } catch (NumberFormatException e) {
            // 如果不是数字，则当作用户名处理
            return getUserByUsername(name);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserStats(Long userId, Long uploaded, Long downloaded) {
        log.info("正在更新用户统计数据 - 用户ID: {}, 上传: {}, 下载: {}", userId, uploaded, downloaded);
        
        try {
            // 使用Mapper直接更新数据库
            int updated = baseMapper.updateUserStats(userId, uploaded, downloaded);
            
            if (updated == 0) {
                String errorMsg = String.format("更新用户统计失败 - 用户ID: %d", userId);
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            log.info("用户统计更新成功 - 用户ID: {}", userId);
            
            // 更新缓存（如果需要）
            User user = getById(userId);
            if (user != null) {
                // 这里可以添加缓存更新逻辑
                log.info("用户当前统计 - 上传: {}, 下载: {}", user.getUploaded(), user.getDownloaded());
            }
        } catch (Exception e) {
            log.error("更新用户统计时发生错误 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            throw new RuntimeException("更新用户统计失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional
    public void updateBonusPoints(Long userId, Integer points) {
        // 更新用户魔力值
        baseMapper.updateBonusPoints(userId, points);
        
        // 记录魔力值变更日志
        UserBonusLog log = new UserBonusLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType(UserBonusLog.TYPE_CHECKIN); // 设置变更类型为签到
        log.setDescription(points > 0 ? "获得魔力值" : "使用魔力值");
        log.setChangeTime(LocalDateTime.now());
        
        userBonusLogMapper.insert(log);
    }

    @Override
    public boolean isEligibleForDownload(Long userId, Long torrentId) {
        System.out.println("=== 检查用户下载权限 ===");
        System.out.println("用户ID: " + userId + ", 种子ID: " + torrentId);
        
        User user = getById(userId);
        if (user == null) {
            System.out.println("ERROR: 用户不存在");
            return false;
        }
        
        System.out.println("用户信息: " + user.getUsername() + ", 等级: " + user.getUserClass() + ", 状态: " + user.getStatus());
        System.out.println("上传量: " + user.getUploaded() + ", 下载量: " + user.getDownloaded());
        
        // 管理员直接允许下载
        if (user.getUserClass().equals(UserClass.ADMIN.getCode())) {
            System.out.println("管理员用户，允许下载");
            return true;
        }
        
        // 检查用户状态
        if (!user.getStatus().equals(UserStatus.NORMAL.getCode())) {
            System.out.println("用户状态异常: " + user.getStatus() + ", 要求: " + UserStatus.NORMAL.getCode());
            return false;
        }
        
        // 检查分享率要求（新用户和上传量较小的用户给予宽松政策）
        Double shareRatio = user.getShareRatio();
        // 如果用户上传量小于1GB或者下载量为0，给予新用户特权
        boolean isNewUser = user.getUploaded() < 1024 * 1024 * 1024L || user.getDownloaded() == 0;
        System.out.println("分享率检查 - 当前分享率: " + shareRatio + ", 是否新用户: " + isNewUser);
        if (!isNewUser && shareRatio < 0.4) {
            System.out.println("用户分享率不足: " + shareRatio + ", 要求: 0.4");
            return false;
        } else if (isNewUser) {
            System.out.println("新用户，跳过分享率检查");
        } else {
            System.out.println("分享率检查通过: " + shareRatio);
        }
        
        // 检查用户是否达到同时下载限制
        UserClass userClass = UserClass.getByCode(user.getUserClass());
        if (userClass != null) {
            // 检查同时下载数量
            int activeDownloads = getActiveDownloads(userId);
            System.out.println("同时下载检查 - 当前: " + activeDownloads + ", 限制: " + userClass.getMaxSimDownloads());
            if (activeDownloads >= userClass.getMaxSimDownloads()) {
                System.out.println("同时下载数量超限");
                return false;
            }
            
            // 检查每日下载限制
            String cacheKey = userId + ":" + LocalDate.now();
            int dailyDownloads = dailyDownloadsCache.getOrDefault(cacheKey, 0);
            System.out.println("每日下载检查 - 当前: " + dailyDownloads + ", 限制: " + userClass.getDailyDownloadLimit());
            if (dailyDownloads >= userClass.getDailyDownloadLimit()) {
                System.out.println("每日下载数量超限");
                return false;
            }
        }
        
        System.out.println("所有权限检查通过，允许下载");
        return true;
    }
    
    /**
     * 获取用户当前活跃下载数量
     */
    private int getActiveDownloads(Long userId) {
        // 从缓存获取，如果不存在则从数据库加载
        return activeDownloadsCache.computeIfAbsent(userId, id -> {
            // 统计正在下载的种子数量
            return peerMapper.selectCount(
                    new LambdaQueryWrapper<Peer>()
                            .eq(Peer::getUserId, id)
                            .eq(Peer::getSeeder, false)
            ).intValue();
        });
    }
    
    /**
     * 记录用户下载种子，更新缓存
     */
    public void recordDownload(Long userId, Long torrentId) {
        // 增加活跃下载计数
        activeDownloadsCache.compute(userId, (key, count) -> count == null ? 1 : count + 1);
        
        // 增加每日下载计数
        String cacheKey = userId + ":" + LocalDate.now();
        dailyDownloadsCache.compute(cacheKey, (key, count) -> count == null ? 1 : count + 1);
        
        // 更新数据库中的下载计数
        incrementDailyDownloadCount(userId);
    }

    @Override
    public String generatePasskey() {
        return DigestUtils.md5Hex(UUID.randomUUID().toString());
    }

    @Override
    public boolean validatePasskey(String passkey) {
        return lambdaQuery()
                .eq(User::getPasskey, passkey)
                .eq(User::getStatus, UserStatus.NORMAL.getCode())
                .exists();
    }

    @Override
    public Integer getDownloadLimit(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return 0;
        }
        
        UserClass userClass = UserClass.getByCode(user.getUserClass());
        return userClass == null ? 5 : userClass.getDailyDownloadLimit(); // 返回每日下载限制
    }

    @Override
    @Transactional
    public Invitation createInvitationCode(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 管理员可以直接创建邀请码，其他用户需要检查等级
        if (!user.isAdmin()) {
            // 检查用户等级，只有高级用户及以上才能生成邀请码
            if (user.getUserClass() < UserClass.ADVANCED.getCode()) {
                throw new RuntimeException("您的等级不足，无法生成邀请码");
            }
        }
        
        // 生成邀请码
        String code = generateInvitationCode();
        
        Invitation invitation = new Invitation();
        invitation.setUserId(userId);
        invitation.setCode(code);
        invitation.setStatus(0);
        invitation.setCreatedTime(LocalDateTime.now());
        
        invitationMapper.insert(invitation);
        
        return invitation;
    }
    
    /**
     * 生成随机邀请码
     */
    private String generateInvitationCode() {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        
        for (int i = 0; i < 16; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return sb.toString();
    }

    @Override
    public Page<UserBonusLog> getUserBonusLogs(Long userId, int page, int size) {
        return userBonusLogMapper.selectPage(
                new Page<>(page, size),
                new LambdaQueryWrapper<UserBonusLog>()
                        .eq(UserBonusLog::getUserId, userId)
                        .orderByDesc(UserBonusLog::getChangeTime)
        );
    }

    @Override
    @Transactional
    public Integer checkIn(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 生成随机魔力值奖励（10-30）
        int bonusPoints = new Random().nextInt(21) + 10;
        
        // 更新用户魔力值
        updateBonusPoints(userId, bonusPoints);
        
        return bonusPoints;
    }

    @Override
    @Transactional
    public void updateWarningCount(Long userId, Integer warningCount) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setWarningCount(warningCount);
        
        // 如果警告次数超过3次，禁用账号
        if (warningCount >= 3) {
            user.setStatus(UserStatus.DISABLED.getCode());
        }
        
        updateById(user);
    }

    @Override
    public User getUserByUsername(String username) {
        return lambdaQuery().eq(User::getUsername, username).one();
    }
    
    @Override
    public User getUserById(Long userId) {
        return getById(userId);
    }
    
    @Override
    @Transactional
    public void updateUser(User user) {
        // 检查用户名是否已存在
        if (lambdaQuery().eq(User::getUsername, user.getUsername())
                .ne(User::getId, user.getId())
                .exists()) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (lambdaQuery().eq(User::getEmail, user.getEmail())
                .ne(User::getId, user.getId())
                .exists()) {
            throw new RuntimeException("邮箱已被使用");
        }

        // 如果用户不是管理员，检查是否满足升级条件
        if (user.getUserClass() != User.USER_CLASS_ADMIN) {
            checkAndUpgradeUser(user);
        }

        updateById(user);
    }
    
    /**
     * 检查并升级用户等级
     */
    private void checkAndUpgradeUser(User user) {
        // 计算用户注册天数
        long registerDays = ChronoUnit.DAYS.between(
            user.getCreatedTime(),
            LocalDateTime.now()
        );

        // 计算分享率
        double ratio = user.getDownloaded() > 0 ? 
            (double) user.getUploaded() / user.getDownloaded() : 
            (user.getUploaded() > 0 ? Double.MAX_VALUE : 0.0);

        // 检查是否满足VIP条件
        if (user.getUserClass() != User.USER_CLASS_VIP &&
            user.getUploaded() >= User.UPLOAD_THRESHOLD_VIP &&
            ratio >= User.RATIO_THRESHOLD_VIP &&
            registerDays >= User.DAYS_THRESHOLD_VIP) {
            user.setUserClass(User.USER_CLASS_VIP);
            return;
        }

        // 检查是否满足高级用户条件
        if (user.getUserClass() != User.USER_CLASS_ADVANCED &&
            user.getUploaded() >= User.UPLOAD_THRESHOLD_ADVANCED &&
            ratio >= User.RATIO_THRESHOLD_ADVANCED &&
            registerDays >= User.DAYS_THRESHOLD_ADVANCED) {
            user.setUserClass(User.USER_CLASS_ADVANCED);
        }
    }

    @Override
    public void updateLastLogin(Long userId) {
        User user = new User();
        user.setId(userId);
        user.setLastLoginTime(LocalDateTime.now());
        updateById(user);
    }
    
    /**
     * 获取用户等级对应的下载速度限制
     */
    public int getUserDownloadSpeedLimit(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return 0;
        }
        
        UserClass userClass = UserClass.getByCode(user.getUserClass());
        return userClass == null ? 512 : (int) userClass.getDownloadSpeedLimit(); // 将long类型转换为int
    }
    
    /**
     * 检查用户是否可以免审核上传种子
     */
    public boolean canUploadWithoutReview(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return false;
        }
        
        UserClass userClass = UserClass.getByCode(user.getUserClass());
        return userClass != null && userClass.isCanUploadWithoutReview();
    }

    @Override
    public Page<User> listUsersByKeyword(String keyword, int page, int size) {
        Page<User> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        if (keyword != null && !keyword.isEmpty()) {
            queryWrapper.like(User::getUsername, keyword)
                        .or()
                        .like(User::getEmail, keyword);
        }
        
        return baseMapper.selectPage(pageParam, queryWrapper);
    }
    
    @Override
    @Transactional
    public void updateUserClass(Long userId, Integer userClass) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setUserClass(userClass);
        updateById(user);
    }
    
    @Override
    @Transactional
    public void updateUserStatus(Long userId, Integer status) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证状态值的有效性
        if (status < 0 || status > 3) {
            throw new RuntimeException("无效的用户状态值");
        }
        
        Integer oldStatus = user.getStatus();
        user.setStatus(status);
        updateById(user);
        
        log.info("用户状态更新成功 - 用户ID: {}, 旧状态: {}, 新状态: {}", userId, oldStatus, status);
        
        // 如果状态变更为禁用，可以考虑清理相关会话
        if (status == 0) {
            log.info("用户 {} 已被禁用", userId);
        }
    }
    
    @Override
    public Map<String, Object> getSiteOverview() {
        // 获取总用户数
        long totalUsers = count();
        
        // 获取总种子数
        long totalTorrents = torrentService.count();
        
        // 获取总上传/下载流量
        Map<String, Object> trafficStats = baseMapper.getTotalTrafficStats();
        
        // 基于现有用户数据计算今日流量（近期注册用户的平均流量）
        long todayUpload = 0L;
        long todayDownload = 0L;
        
        try {
            // 获取今天注册的用户的平均上传下载量
            List<Map<String, Object>> todayStats = baseMapper.getDailyTrafficStats(1);
            if (!todayStats.isEmpty()) {
                Map<String, Object> todayData = todayStats.get(0);
                todayUpload = ((Number) todayData.getOrDefault("upload", 0L)).longValue();
                todayDownload = ((Number) todayData.getOrDefault("download", 0L)).longValue();
            }
        } catch (Exception e) {
            // 如果查询失败，使用默认值
            todayUpload = 0L;
            todayDownload = 0L;
        }
        
        Map<String, Object> result = new java.util.HashMap<>();
        result.put("totalUsers", totalUsers);
        result.put("totalTorrents", totalTorrents);
        result.put("todayUpload", todayUpload);
        result.put("todayDownload", todayDownload);
        
        // 如果trafficStats不为空，也包含总统计数据
        if (trafficStats != null) {
            result.put("totalUploaded", trafficStats.get("totalUploaded"));
            result.put("totalDownloaded", trafficStats.get("totalDownloaded"));
        } else {
            result.put("totalUploaded", 0L);
            result.put("totalDownloaded", 0L);
        }
        
        return result;
    }
    
    @Override
    public Map<String, Object> getDailyTrafficStats(int days) {
        // 获取每日流量统计
        List<Map<String, Object>> dailyStats = baseMapper.getDailyTrafficStats(days);
        
        Map<String, Object> result = new java.util.HashMap<>();
        result.put("dailyStats", dailyStats);
        
        return result;
    }
    
    @Override
    public Map<String, Object> getDailyTrafficStats(int days, String startDate, String endDate) {
        // 如果指定了日期范围，使用基于日期范围的查询
        if (startDate != null && endDate != null) {
            List<Map<String, Object>> dailyStats = baseMapper.getDailyTrafficStatsByDateRange(startDate, endDate);
            Map<String, Object> result = new java.util.HashMap<>();
            result.put("dailyStats", dailyStats);
            return result;
        } else {
            // 否则使用原有的基于天数的查询
            return getDailyTrafficStats(days);
        }
    }
    
    @Override
    public Map<String, Object> getActiveUserStats(int days) {
        // 获取活跃用户统计
        List<Map<String, Object>> activeStats = baseMapper.getActiveUserStats(days);
        
        Map<String, Object> result = new java.util.HashMap<>();
        result.put("activeUsers", activeStats);
        
        return result;
    }
    
    @Override
    public Map<String, Object> getActiveUserStats(int days, String startDate, String endDate) {
        // 如果指定了日期范围，使用基于日期范围的查询
        if (startDate != null && endDate != null) {
            List<Map<String, Object>> activeStats = baseMapper.getActiveUserStatsByDateRange(startDate, endDate);
            Map<String, Object> result = new java.util.HashMap<>();
            result.put("activeUsers", activeStats);
            return result;
        } else {
            // 否则使用原有的基于天数的查询
            return getActiveUserStats(days);
        }
    }

    @Override
    @Transactional
    public User updateUserProfile(UpdateProfileRequest request) {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }

        // 更新用户信息
        if (request.getEmail() != null && !request.getEmail().equals(currentUser.getEmail())) {
            // 检查邮箱是否已被使用
            User existingUser = lambdaQuery().eq(User::getEmail, request.getEmail()).one();
            if (existingUser != null && !existingUser.getId().equals(currentUser.getId())) {
                throw new RuntimeException("该邮箱已被使用");
            }
            currentUser.setEmail(request.getEmail());
        }

        if (request.getNickname() != null) {
            currentUser.setUsername(request.getNickname());
        }

        if (request.getBio() != null) {
            currentUser.setSignature(request.getBio());
        }

        updateById(currentUser);
        return currentUser;
    }

    @Override
    @Transactional
    public void changeUserPassword(ChangePasswordRequest request) {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }

        // 验证当前密码
        if (!passwordEncoder.matches(request.getOldPassword(), currentUser.getPassword())) {
            throw new RuntimeException("当前密码不正确");
        }

        // 更新密码
        currentUser.setPassword(passwordEncoder.encode(request.getNewPassword()));
        updateById(currentUser);
    }

    @Override
    public UserStatsResponse getUserStats(Long userId) {
        if (userId == null) {
            User currentUser = getCurrentUser();
            if (currentUser == null) {
                throw new RuntimeException("用户未登录");
            }
            userId = currentUser.getId();
        }

        log.info("Getting user stats for userId: {}", userId);
        UserStatsResponse stats = new UserStatsResponse();

        try {
            // 获取基本统计信息，添加空值检查
            Integer torrentCount = baseMapper.getUserTorrentCount(userId);
            Integer seedingCount = baseMapper.getUserSeedingCount(userId);
            Integer leechingCount = baseMapper.getUserLeechingCount(userId);
            Integer inviteCount = baseMapper.getUserInviteCount(userId);
        Integer topicCount = baseMapper.getUserTopicCount(userId);
        
            stats.setTorrentCount(torrentCount != null ? torrentCount : 0);
            stats.setSeedingCount(seedingCount != null ? seedingCount : 0);
            stats.setLeechingCount(leechingCount != null ? leechingCount : 0);
            stats.setInviteCount(inviteCount != null ? inviteCount : 0);
            stats.setTopicCount(topicCount != null ? topicCount : 0);

            log.info("Basic stats - torrent: {}, seeding: {}, leeching: {}, invite: {}, topic: {}", 
                    stats.getTorrentCount(), stats.getSeedingCount(), stats.getLeechingCount(), 
                    stats.getInviteCount(), stats.getTopicCount());

        // 获取今日统计
            try {
        Map<String, Object> todayStats = baseMapper.getUserTodayStats(userId);
                if (todayStats != null) {
        stats.setTodayUpload(((Number) todayStats.getOrDefault("todayUpload", 0L)).longValue());
        stats.setTodayDownload(((Number) todayStats.getOrDefault("todayDownload", 0L)).longValue());
                } else {
                    stats.setTodayUpload(0L);
                    stats.setTodayDownload(0L);
                }
            } catch (Exception e) {
                log.warn("Failed to get today stats for user {}: {}", userId, e.getMessage());
                stats.setTodayUpload(0L);
                stats.setTodayDownload(0L);
            }

        // 获取本周统计
            try {
        Map<String, Object> weekStats = baseMapper.getUserWeekStats(userId);
                if (weekStats != null) {
        stats.setWeekUpload(((Number) weekStats.getOrDefault("weekUpload", 0L)).longValue());
        stats.setWeekDownload(((Number) weekStats.getOrDefault("weekDownload", 0L)).longValue());
                } else {
                    stats.setWeekUpload(0L);
                    stats.setWeekDownload(0L);
                }
            } catch (Exception e) {
                log.warn("Failed to get week stats for user {}: {}", userId, e.getMessage());
                stats.setWeekUpload(0L);
                stats.setWeekDownload(0L);
            }

        // 获取本月统计
            try {
        Map<String, Object> monthStats = baseMapper.getUserMonthStats(userId);
                if (monthStats != null) {
        stats.setMonthUpload(((Number) monthStats.getOrDefault("monthUpload", 0L)).longValue());
        stats.setMonthDownload(((Number) monthStats.getOrDefault("monthDownload", 0L)).longValue());
                } else {
                    stats.setMonthUpload(0L);
                    stats.setMonthDownload(0L);
                }
            } catch (Exception e) {
                log.warn("Failed to get month stats for user {}: {}", userId, e.getMessage());
                stats.setMonthUpload(0L);
                stats.setMonthDownload(0L);
            }

        } catch (Exception e) {
            log.error("Error getting user stats for user {}: {}", userId, e.getMessage(), e);
            // 返回默认值
            stats.setTorrentCount(0);
            stats.setSeedingCount(0);
            stats.setLeechingCount(0);
            stats.setInviteCount(0);
            stats.setTopicCount(0);
            stats.setTodayUpload(0L);
            stats.setTodayDownload(0L);
            stats.setWeekUpload(0L);
            stats.setWeekDownload(0L);
            stats.setMonthUpload(0L);
            stats.setMonthDownload(0L);
        }

        log.info("Final stats for user {}: torrentCount={}, topicCount={}, seedingCount={}, leechingCount={}, inviteCount={}", 
                userId, stats.getTorrentCount(), stats.getTopicCount(), stats.getSeedingCount(), stats.getLeechingCount(), stats.getInviteCount());
        
        return stats;
    }

    @Override
    @Transactional
    public String regeneratePasskey() {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }

        // 生成新的passkey
        String newPasskey = generatePasskey();
        currentUser.setPasskey(newPasskey);
        updateById(currentUser);

        return newPasskey;
    }

    @Override
    public UserProfileResponse getCurrentUserProfile() {
        User user = getCurrentUser();
        if (user == null) {
            return null;
        }
        
        UserProfileResponse profile = new UserProfileResponse();
        profile.setId(user.getId());
        profile.setUsername(user.getUsername());
        profile.setEmail(user.getEmail());
        profile.setStatus(user.getStatus());
        profile.setUserClass(user.getUserClass());
        profile.setUploaded(user.getUploaded());
        profile.setDownloaded(user.getDownloaded());
        profile.setBonusPoints(user.getBonusPoints());
        profile.setPasskey(user.getPasskey());
        profile.setCreatedTime(user.getCreatedTime());
        profile.setLastLoginTime(user.getLastLoginTime());
        profile.setLastLoginIp(user.getLastLoginIp());
        profile.setAvatar(user.getAvatar());
        profile.setSignature(user.getSignature());
        profile.setAssessmentDeadline(user.getAssessmentDeadline());
        profile.setWarningCount(user.getWarningCount());
        
        return profile;
    }

    @Override
    public Page<Invitation> getInvitationList(int page, int size) {
        Page<Invitation> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Invitation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Invitation::getCreatedTime);
        
        return invitationMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    @Transactional
    public void deleteInvitationCode(Long invitationId) {
        // 检查邀请码是否存在
        Invitation invitation = invitationMapper.selectById(invitationId);
        if (invitation == null) {
            throw new RuntimeException("邀请码不存在");
        }
        
        // 检查邀请码是否已被使用，已使用的邀请码不能删除
        if (invitation.getStatus() == 1) {
            throw new RuntimeException("已使用的邀请码不能删除");
        }
        
        // 删除邀请码
        invitationMapper.deleteById(invitationId);
    }

    @Override
    public UserProfileResponse getUserProfile(Long userId, Long viewerId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        UserProfileResponse response = new UserProfileResponse();
        response.setId(user.getId());
        response.setUsername(user.getUsername());
        response.setUserClass(user.getUserClass());
        response.setCreatedTime(user.getCreatedTime());
        response.setAvatar(user.getAvatar());
        response.setStatus(user.getStatus());
        response.setWarningCount(user.getWarningCount() != null ? user.getWarningCount() : 0);
        
        // 判断是否查看自己的资料
        boolean isOwnProfile = viewerId != null && viewerId.equals(userId);
        
        // 解析用户的隐私设置
        PrivacySettings privacySettings = parsePrivacySettings(user.getSignature());
        
        // 如果是查看自己的资料或者用户设置公开，显示完整信息
        if (isOwnProfile || privacySettings.getShowEmail()) {
            response.setEmail(user.getEmail());
        }
        
        if (isOwnProfile || privacySettings.getShowStats()) {
            response.setUploaded(user.getUploaded() != null ? user.getUploaded() : 0L);
            response.setDownloaded(user.getDownloaded() != null ? user.getDownloaded() : 0L);
            response.setBonusPoints(user.getBonusPoints() != null ? user.getBonusPoints() : 0);
        } else {
            // 不显示统计信息时设为0或null
            response.setUploaded(0L);
            response.setDownloaded(0L);
            response.setBonusPoints(0);
        }
        
        if (isOwnProfile || privacySettings.getShowActivity()) {
            response.setLastLoginTime(user.getLastLoginTime());
            response.setLastLoginIp(user.getLastLoginIp());
        }
        
        // 显示个性签名（从设置中解析）
        String signature = parseSignatureFromSettings(user.getSignature());
        response.setSignature(signature);
        
        // 如果是查看自己的资料，显示passkey
        if (isOwnProfile) {
            response.setPasskey(user.getPasskey());
            response.setAssessmentDeadline(user.getAssessmentDeadline());
        }
        
        return response;
    }
    
    private PrivacySettings parsePrivacySettings(String signature) {
        PrivacySettings defaultSettings = new PrivacySettings();
        defaultSettings.setShowEmail(false);
        defaultSettings.setShowStats(true);
        defaultSettings.setShowActivity(true);
        
        System.out.println("=== 解析隐私设置 ===");
        System.out.println("signature内容: " + signature);
        
        if (signature == null || !signature.startsWith("{")) {
            System.out.println("signature为空或不是JSON格式，使用默认设置");
            return defaultSettings;
        }
        
        try {
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> settings = mapper.readValue(signature, java.util.Map.class);
            System.out.println("解析的设置: " + settings);
            
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> privacy = (java.util.Map<String, Object>) settings.get("privacy");
            System.out.println("隐私设置部分: " + privacy);
            
            if (privacy != null) {
                PrivacySettings privacySettings = new PrivacySettings();
                privacySettings.setShowEmail((Boolean) privacy.getOrDefault("showEmail", false));
                privacySettings.setShowStats((Boolean) privacy.getOrDefault("showStats", true));
                privacySettings.setShowActivity((Boolean) privacy.getOrDefault("showActivity", true));
                System.out.println("解析后的隐私设置 - showEmail: " + privacySettings.getShowEmail() + 
                                 ", showStats: " + privacySettings.getShowStats() + 
                                 ", showActivity: " + privacySettings.getShowActivity());
                return privacySettings;
            }
        } catch (Exception e) {
            System.out.println("JSON解析失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        System.out.println("使用默认隐私设置");
        return defaultSettings;
    }
    
    private String parseSignatureFromSettings(String signature) {
        if (signature == null || !signature.startsWith("{")) {
            return signature; // 如果不是JSON格式，直接返回
        }
        
        try {
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> settings = mapper.readValue(signature, java.util.Map.class);
            return (String) settings.get("signature");
        } catch (Exception e) {
            return ""; // 解析失败返回空字符串
        }
    }
    
    // 内部类用于隐私设置
    private static class PrivacySettings {
        private Boolean showEmail;
        private Boolean showStats;
        private Boolean showActivity;
        
        public Boolean getShowEmail() { return showEmail; }
        public void setShowEmail(Boolean showEmail) { this.showEmail = showEmail; }
        
        public Boolean getShowStats() { return showStats; }
        public void setShowStats(Boolean showStats) { this.showStats = showStats; }
        
        public Boolean getShowActivity() { return showActivity; }
        public void setShowActivity(Boolean showActivity) { this.showActivity = showActivity; }
    }
    
    @Override
    public UserSettingsResponse getUserSettings() {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }
        
        UserSettingsResponse response = new UserSettingsResponse();
        
        // 解析signature字段中的设置（JSON格式）
        String signature = currentUser.getSignature();
        if (signature != null && signature.startsWith("{")) {
            try {
                // 简单的JSON解析，实际项目中可以使用更完善的JSON库
                com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
                @SuppressWarnings("unchecked")
                java.util.Map<String, Object> settings = mapper.readValue(signature, java.util.Map.class);
                
                // 解析通知设置
                @SuppressWarnings("unchecked")
                java.util.Map<String, Object> notifications = (java.util.Map<String, Object>) settings.get("notifications");
                if (notifications != null) {
                    UserSettingsResponse.NotificationSettings notificationSettings = new UserSettingsResponse.NotificationSettings();
                    notificationSettings.setEmailNotifications((Boolean) notifications.getOrDefault("emailNotifications", true));
                    notificationSettings.setTorrentNotifications((Boolean) notifications.getOrDefault("torrentNotifications", true));
                    notificationSettings.setMessageNotifications((Boolean) notifications.getOrDefault("messageNotifications", true));
                    notificationSettings.setSystemNotifications((Boolean) notifications.getOrDefault("systemNotifications", false));
                    response.setNotifications(notificationSettings);
                }
                
                // 解析隐私设置
                @SuppressWarnings("unchecked")
                java.util.Map<String, Object> privacy = (java.util.Map<String, Object>) settings.get("privacy");
                if (privacy != null) {
                    UserSettingsResponse.PrivacySettings privacySettings = new UserSettingsResponse.PrivacySettings();
                    privacySettings.setShowEmail((Boolean) privacy.getOrDefault("showEmail", false));
                    privacySettings.setShowStats((Boolean) privacy.getOrDefault("showStats", true));
                    privacySettings.setShowActivity((Boolean) privacy.getOrDefault("showActivity", true));
                    response.setPrivacy(privacySettings);
                }
                
                // 个性签名
                response.setSignature((String) settings.get("signature"));
                
            } catch (Exception e) {
                // JSON解析失败，使用默认设置
                setDefaultSettings(response);
            }
        } else {
            // 没有设置或格式不正确，使用默认设置
            setDefaultSettings(response);
            // 如果signature不是JSON格式，则作为个性签名处理
            if (signature != null && !signature.startsWith("{")) {
                response.setSignature(signature);
            }
        }
        
        return response;
    }
    
    @Override
    @Transactional
    public void saveUserSettings(UserSettingsRequest request) {
        User currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }
        
        try {
            // 构建设置JSON
            java.util.Map<String, Object> settings = new java.util.HashMap<>();
            
            // 通知设置
            if (request.getNotifications() != null) {
                java.util.Map<String, Object> notifications = new java.util.HashMap<>();
                notifications.put("emailNotifications", request.getNotifications().getEmailNotifications());
                notifications.put("torrentNotifications", request.getNotifications().getTorrentNotifications());
                notifications.put("messageNotifications", request.getNotifications().getMessageNotifications());
                notifications.put("systemNotifications", request.getNotifications().getSystemNotifications());
                settings.put("notifications", notifications);
            }
            
            // 隐私设置
            if (request.getPrivacy() != null) {
                java.util.Map<String, Object> privacy = new java.util.HashMap<>();
                privacy.put("showEmail", request.getPrivacy().getShowEmail());
                privacy.put("showStats", request.getPrivacy().getShowStats());
                privacy.put("showActivity", request.getPrivacy().getShowActivity());
                settings.put("privacy", privacy);
            }
            
            // 个性签名
            if (request.getSignature() != null) {
                settings.put("signature", request.getSignature());
            }
            
            // 转换为JSON字符串
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            String settingsJson = mapper.writeValueAsString(settings);
            
            // 保存到signature字段
            currentUser.setSignature(settingsJson);
            updateById(currentUser);
            
        } catch (Exception e) {
            throw new RuntimeException("保存设置失败: " + e.getMessage());
        }
    }
    
    private void setDefaultSettings(UserSettingsResponse response) {
        // 默认通知设置
        UserSettingsResponse.NotificationSettings notificationSettings = new UserSettingsResponse.NotificationSettings();
        notificationSettings.setEmailNotifications(true);
        notificationSettings.setTorrentNotifications(true);
        notificationSettings.setMessageNotifications(true);
        notificationSettings.setSystemNotifications(false);
        response.setNotifications(notificationSettings);
        
        // 默认隐私设置
        UserSettingsResponse.PrivacySettings privacySettings = new UserSettingsResponse.PrivacySettings();
        privacySettings.setShowEmail(false);
        privacySettings.setShowStats(true);
        privacySettings.setShowActivity(true);
        response.setPrivacy(privacySettings);
        
        // 默认个性签名为空
        response.setSignature("");
    }

    /**
     * 检查并更新用户考核状态
     */
    @Override
    @Transactional
    public Map<String, Object> checkUserAssessment(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("userId", userId);
        result.put("username", user.getUsername());
        result.put("currentStatus", user.getStatus());
        
        // 只对考核中的用户进行检查
        if (!user.getStatus().equals(UserStatus.ASSESSMENT.getCode())) {
            result.put("message", "用户不在考核期");
            return result;
        }
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime deadline = user.getAssessmentDeadline();
        
        if (deadline == null) {
            result.put("message", "考核截止时间未设置");
            return result;
        }
        
        boolean isExpired = now.isAfter(deadline);
        result.put("isExpired", isExpired);
        result.put("deadline", deadline);
        result.put("daysRemaining", ChronoUnit.DAYS.between(now, deadline));
        
        // 检查考核要求
        boolean uploadRequirementMet = user.getUploaded() >= UserConstant.MIN_UPLOAD_BYTES;
        double shareRatio = user.getDownloaded() > 0 ? 
            (double) user.getUploaded() / user.getDownloaded() : 
            (user.getUploaded() > 0 ? Double.MAX_VALUE : 0.0);
        boolean shareRatioRequirementMet = shareRatio >= UserConstant.MIN_SHARE_RATIO;
        
        result.put("uploadRequirementMet", uploadRequirementMet);
        result.put("shareRatioRequirementMet", shareRatioRequirementMet);
        result.put("currentUploaded", user.getUploaded());
        result.put("requiredUploaded", UserConstant.MIN_UPLOAD_BYTES);
        result.put("currentShareRatio", shareRatio);
        result.put("requiredShareRatio", UserConstant.MIN_SHARE_RATIO);
        
        if (isExpired) {
            // 考核期已过，检查是否通过
            if (uploadRequirementMet && shareRatioRequirementMet) {
                // 考核通过，升级为正常用户
                user.setStatus(UserStatus.NORMAL.getCode());
                user.setAssessmentDeadline(null);
                updateById(user);
                result.put("assessmentResult", "PASSED");
                result.put("message", "考核通过，账户已激活");
            } else {
                // 考核失败，禁用账户
                user.setStatus(UserStatus.DISABLED.getCode());
                updateById(user);
                result.put("assessmentResult", "FAILED");
                result.put("message", "考核失败，账户已被禁用");
            }
        } else {
            result.put("assessmentResult", "IN_PROGRESS");
            result.put("message", "考核进行中");
        }
        
        return result;
    }

    /**
     * 批量检查所有考核期用户
     */
    @Override
    @Transactional
    public List<Map<String, Object>> batchCheckAssessments() {
        List<User> assessmentUsers = lambdaQuery()
                .eq(User::getStatus, UserStatus.ASSESSMENT.getCode())
                .isNotNull(User::getAssessmentDeadline)
                .list();
        
        List<Map<String, Object>> results = new ArrayList<>();
        for (User user : assessmentUsers) {
            try {
                Map<String, Object> result = checkUserAssessment(user.getId());
                results.add(result);
            } catch (Exception e) {
                log.error("检查用户考核状态失败: userId={}, error={}", user.getId(), e.getMessage());
            }
        }
        
        return results;
    }

    /**
     * 为用户设置考核期
     */
    @Override
    @Transactional
    public void setUserAssessment(Long userId, Integer assessmentDays) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        if (assessmentDays == null || assessmentDays <= 0) {
            assessmentDays = (int) UserConstant.ASSESSMENT_PERIOD_DAYS;
        }
        
        user.setStatus(UserStatus.ASSESSMENT.getCode());
        user.setAssessmentDeadline(LocalDateTime.now().plusDays(assessmentDays));
        updateById(user);
        
        log.info("用户考核期设置成功 - 用户ID: {}, 考核天数: {}, 截止时间: {}", 
                userId, assessmentDays, user.getAssessmentDeadline());
    }

    /**
     * 取消用户考核，恢复正常状态
     */
    @Override
    @Transactional
    public void cancelUserAssessment(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(UserStatus.NORMAL.getCode());
        user.setAssessmentDeadline(null);
        updateById(user);
        
        log.info("用户考核已取消 - 用户ID: {}", userId);
    }

    @Override
    public boolean checkDownloadLimit(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return false;
        }

        // 获取用户今日下载次数
        Integer dailyCount = getDailyDownloadCount(userId);
        user.setDailyDownloadCount(dailyCount);

        // 获取用户下载限制
        Integer limit = user.getDailyDownloadLimit();
        user.setDailyDownloadLimit(limit);

        // VIP用户和管理员无限制
        if (limit == -1) {
            return true;
        }

        return dailyCount < limit;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementDailyDownloadCount(Long userId) {
        LocalDate today = LocalDate.now();
        
        log.info("正在更新用户下载计数 - 用户ID: {}, 日期: {}", userId, today);
        
        try {
            // 使用原子操作插入或更新记录
            int result = userDailyDownloadMapper.insertOrIncrementDownloadCount(userId, today);
            
            if (result == 0) {
                String errorMsg = "更新下载记录失败 - 用户ID: " + userId;
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            // 更新缓存
            String cacheKey = userId + ":" + today;
            dailyDownloadsCache.compute(cacheKey, (key, count) -> count == null ? 1 : count + 1);
            dailyDownloadsExpireTime.put(cacheKey, System.currentTimeMillis() + 24 * 60 * 60 * 1000); // 24小时后过期
            
            log.info("下载计数更新完成 - 用户ID: {}", userId);
        } catch (Exception e) {
            log.error("更新下载计数时发生错误 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            throw new RuntimeException("更新下载计数失败: " + e.getMessage(), e);
        }
    }

    @Override
    public Integer getDailyDownloadCount(Long userId) {
        LocalDate today = LocalDate.now();
        UserDailyDownload record = userDailyDownloadMapper.selectOne(
            new QueryWrapper<UserDailyDownload>()
                .eq("user_id", userId)
                .eq("download_date", today)
        );
        return record != null ? record.getDownloadCount() : 0;
    }

    @Override
    public User login(String username, String password) {
        // 验证用户凭据
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
        );
        
        // 获取用户信息
        User user = getUserByUsername(username);
        if (user != null) {
            // 更新最后登录时间
            user.setLastLoginTime(LocalDateTime.now());
            updateById(user);
        }
        
        return user;
    }

    @Override
    @Transactional
    public void updateUserAdminStatus(Long userId, Boolean isAdmin) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 不允许修改ID为1的用户的管理员身份
        if (userId == 1) {
            throw new RuntimeException("不能修改超级管理员的管理员身份");
        }
        
        // 更新用户等级
        user.setUserClass(isAdmin ? User.USER_CLASS_ADMIN : User.USER_CLASS_NORMAL);
        userMapper.updateById(user);
    }

    @Override
    public User getByPasskey(String passkey) {
        return lambdaQuery()
                .eq(User::getPasskey, passkey)
                .one();
    }
} 